package io.gitee.zhangbinhub.admin.gateway.conf

import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import org.noear.solon.Utils
import org.noear.solon.cloud.CloudConfigHandler
import org.noear.solon.cloud.annotation.CloudConfig
import org.noear.solon.cloud.gateway.CloudGatewayConfiguration
import org.noear.solon.cloud.gateway.CloudRouteRegister
import org.noear.solon.cloud.gateway.properties.GatewayProperties
import org.noear.solon.cloud.gateway.route.RouteFactoryManager
import org.noear.solon.cloud.model.Config
import org.noear.solon.core.Props
import kotlin.reflect.KProperty1
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.jvm.isAccessible

@CloudConfig(name = $$"${solon.app.name}-${solon.env}.yaml", group = $$"${solon.app.group}", autoRefreshed = true)
class GateWayConfigHandler(
    private val logAdapter: LogAdapter,
    private val cloudRouteRegister: CloudRouteRegister,
    private val routeFactoryManager: RouteFactoryManager
) : CloudConfigHandler {
    override fun handle(config: Config) {
        logAdapter.info("The implementation class of CloudRouteRegister is ${cloudRouteRegister.javaClass.name}")
        if (cloudRouteRegister is CloudGatewayConfiguration) {
            val gatewayProps = Props(config.toProps()).getProp(GatewayProperties.SOLON_CLOUD_GATEWAY)
            if (gatewayProps.isNotEmpty()) {
                gatewayProps.toBean(GatewayProperties::class.java).let { gatewayProperties ->
                    logAdapter.info("[ Begin] 开始更新路由...")
                    val kClass = cloudRouteRegister::class

                    //清除默认过滤器
                    kClass.declaredMemberProperties.find { it.name == "routeDefaultFilters" }?.let { kProperty ->
                        @Suppress("UNCHECKED_CAST")
                        (kProperty as? KProperty1<CloudGatewayConfiguration, MutableList<*>>)?.let { property ->
                            property.isAccessible = true
                            property.get(cloudRouteRegister)
                        }
                    }?.apply {
                        logAdapter.info("[Delete] 删除默认过滤器：${this.size} 条")
                    }?.clear()
                    //添加默认过滤器
                    if (Utils.isNotEmpty(gatewayProperties.defaultFilters)) {
                        logAdapter.info("[   Add] 添加默认过滤器: ${gatewayProperties.defaultFilters.size} 条")
                        for (defaultFilter in gatewayProperties.defaultFilters) {
                            cloudRouteRegister.routeDefaultFilter(routeFactoryManager.buildFilter(defaultFilter))
                        }
                    }

                    //更新路由
                    val newRouteIds = gatewayProperties.routes.map { it.id }
                    kClass.declaredMemberProperties.find { it.name == "routes" }?.let { kProperty ->
                        @Suppress("UNCHECKED_CAST")
                        (kProperty as? KProperty1<CloudGatewayConfiguration, MutableMap<String, *>>)?.let { property ->
                            property.isAccessible = true
                            property.get(cloudRouteRegister)
                        }
                    }?.also { routes ->
                        routes.filter { !newRouteIds.contains(it.key) }.let { delRoutes ->
                            delRoutes.forEach {
                                routes.remove(it.key)
                                logAdapter.info("[Delete] 删除路由：${it.key}")
                            }
                        }
                    }
                    if (gatewayProperties.routes.isNotEmpty()) {
                        cloudRouteRegister.route(gatewayProperties)
                        logAdapter.info("[Update] 更新路由: ${gatewayProperties.routes.joinToString(separator = ",") { it.id }}")
                    }
                    logAdapter.info("[   End] 路由更新完成!")
                }
            }
        }
    }
}